<!--屏幕超时未操作锁定对话框-->
<template>
	<a-modal v-bind="options" class="screen-lock-dialog">
		<a-card :bordered="false">
			<a-card-meta title="重新登录" description="当前登录已超时，请输入密码重新登录">
				<template #avatar>
					<a-avatar :size="46" :src="currentUser.headPortraitUrl">
						<template #icon>
							<user-outlined />
						</template>
					</a-avatar>
				</template>
			</a-card-meta>
			<a-form :model="loginState" name="login" layout="vertical" :rules="loginRules" @finish="login">
				<a-form-item name="password">
					<a-input-group compact style="display: flex">
						<a-input v-model:value="loginState.password" type="password" size="large" allow-clear :maxlength="16" autocomplete="new-password" placeholder="请输入密码" style="flex: 1" />
						<a-button type="primary" :loading="loading" html-type="submit" size="large">
							<import-outlined v-if="!loading" :rotate="180" />
							登录
						</a-button>
						<a-button @click="logout" size="large">退出</a-button>
					</a-input-group>
				</a-form-item>
			</a-form>
		</a-card>
	</a-modal>
</template>

<script lang="ts" setup>
	import {createVNode, onMounted, onUnmounted, reactive, ref, toRef} from 'vue'
	import { message, Modal } from 'ant-design-vue'
	import {ImportOutlined, QuestionCircleOutlined, UserOutlined} from '@ant-design/icons-vue'
	import {validatePassword} from '@/utils/formValidation'
	import {Rule} from 'ant-design-vue/es/form'
	import {useStore} from '@/store'
	import {isDevEnv} from 'yuxin-base/src/utils'
	import {microApps} from '@/micros/apps'
	import { getMenusList, getUserToken } from '@/api/user'

	const store = useStore()

	const options = reactive({
		width: 435,
		closable: false,
		footer: null,
		centered: true,
		maskClosable: false,
		destroyOnClose: true,
		zIndex: 1001,
		visible: toRef(store, 'lockVisible'),
		onCancel() {
			loginState.password = null
		}
	})

	const { currentUser, enterprise }: any = store

	const loginState = reactive<any>({
		grant_type: 'password',
		no: enterprise.no,
		mobile: currentUser.phone,
		password: null
	})

	const loginRules: Record<string, Rule[]> = {
		password: [{ required: true, validator: validatePassword }]
	}

	const loading = ref<boolean>(false)

	// 开发环境不启动锁屏定时器
	if (!isDevEnv()) {
		const onMouseMove = () => {
			localStorage.setItem('last_operation_time', Date.now().toString())
		}

		onMounted(() => document.addEventListener('mousemove', onMouseMove))
		onUnmounted(() => document.removeEventListener('mousemove', onMouseMove))

		// 定时器每分钟检查鼠标最后一次操作时间是否超过10分钟
		setInterval(() => {
			let last_operation_time = localStorage.getItem('last_operation_time')
			if (last_operation_time) {
				if (Date.now() - Number(last_operation_time) > 3 * 60 * 60 * 1000) {
					store.$reset()
					store.lockVisible = true
					// 锁屏后需要移除所有手动加载过的微应用，避免解锁后无法渲染
					microApps.removeAll()
				}
			}
		}, 60 * 1000)
	}

	/**
	 * 登录请求
	 */
	const login = async () => {
		loading.value = true
		await loginStep().catch(() => {})
		loading.value = false
	}
	const loginStep = async () => {
		const { token, enterprise } = await getToken()
		const menu = await getMenu()
		store.userLogin({ loginState, token, enterprise, menu, type: 'again' })
			.then(() => (store.lockVisible = false))
			.finally(() => (loading.value = false))
	}
	const getToken = async () => {
		const { data } = await getUserToken(loginState)
		const { token, shopInfo: enterprise } = data || {}
		if (!token.value) {
			message.error('获取 token 失败，请联系管理员')
			return Promise.reject()
		}
		store.setAccessToken(token.value)
		store.setEnterprise(enterprise)
		return { token: token.value, enterprise }
	}
	const getMenu = async () => {
		const { data } = await getMenusList()
		if (!Array.isArray(data)) {
			message.error('菜单数据有误，请联系管理员')
			return Promise.reject()
		}
		if (!data.length) {
			message.error('当前账号无权限访问系统')
			return Promise.reject()
		}
		return data
	}
	/**
	 * 退出登录 重定向login
	 */
	const logout = () => {
		Modal.confirm({
			title: '系统提示',
			mask: true,
			centered: true,
			zIndex: 1010,
			icon: createVNode(QuestionCircleOutlined),
			content: '您确定要退出系统吗？',
			async onOk() {
				await store.userLogout()
			}
		})
	}
</script>

<style lang="less">
	.screen-lock-dialog {
		.ant-modal-body {
			padding: 0;

			.ant-card-body {
				padding-top: 36px;
				padding-bottom: 12px;

				.ant-card-meta {
					margin-bottom: 32px;

					.ant-card-meta-title {
						margin-bottom: 5px;
					}
				}
			}
		}
	}
</style>
